﻿using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

namespace ScFramework.Core
{
    public class UserManager : SystemModule, INeedRemove
    {
        static UserManager _instance = null;

        public override void Initialize(Main m)
        {
            base.Initialize(m);
            _instance = this;
        }

        public static bool IsHost
        {
            get => _instance._main.TempUserID == 1;
        }

        List<int> _users = new List<int> {1};
        Dictionary<int, UserState> _userState = new Dictionary<int, UserState>();

        public List<int> Users
        {
            get { return _users; }
        }

        Dictionary<Tuple<UserState, UserState>, UserStateAcionPair> userActionDic =
            new Dictionary<Tuple<UserState, UserState>, UserStateAcionPair>();

        public static UserState GetUserState(int id)
        {
            if (_instance._userState.ContainsKey(id) == false)
            {
                _instance._userState[id] = UserState.Null;
            }

            return _instance._userState[id];
        }

        public static void SetUserState(int id, UserState state)
        {
            if (IsHost == false)
            {
                return;
            }

            if (GetUserState(id) == state)
            {
                return;
            }
            else
            {
                if (_instance.userActionDic.ContainsKey(new Tuple<UserState, UserState>(GetUserState(id), state)))
                    _instance.userActionDic[new Tuple<UserState, UserState>(GetUserState(id), state)].DoActon(id);
                _instance._userState[id] = state;
            }
        }

        public void RegisterUserEvent(Action<int> action, UserState lst, UserState nxt, int order = 0)
        {
            var key = new Tuple<UserState, UserState>(lst, nxt);
            if (userActionDic.ContainsKey(key) == false)
            {
                userActionDic[key] = new UserStateAcionPair();
            }

            userActionDic[key].Add(action, order);
        }

        public void RemoveAbout(object obj)
        {
            foreach (var x in userActionDic.Values)
            {
                x.Remove(obj);
            }
        }

        /// <summary>
        /// 0:无用户
        /// 1:host
        /// 2...:guest
        /// </summary>
        public static int UserID
        {
            get => _instance._main.TempUserID;
        }

        public override void SysUpdate(float deltaTime)
        {
            base.SysUpdate(deltaTime);
        }
    }

    public class UserStateAcionPair
    {
        public UserStateAcionPair()
        {
        }

        List<Tuple<int, Action<int>>> Actions = new List<Tuple<int, Action<int>>>();

        public void DoActon(int id)
        {
            Actions.Sort((Tuple<int, Action<int>> a, Tuple<int, Action<int>> b) =>
            {
                if (a.Item1 < b.Item1) return -1;
                else if (a.Item1 > b.Item1) return 1;
                else return 0;
            });
            var _action = Actions.ConvertAll(s => s);
            foreach (var x in _action)
            {
                x.Item2(id);
            }
        }

        public void Add(Action<int> act, int order)
        {
            Actions.Add(new Tuple<int, Action<int>>(order, act));
        }

        public void Remove(object obj)
        {
            Actions.RemoveAll(s => s.Item2.Target == obj);
        }
    }

    public enum UserState
    {
        Null,
        OnCombine,
        OnGame
    }
}